package com.zut.wx.redis;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class redisConfig {

    /**
     * 原来的jdk序列化规则不好用，容易产生乱码，重新配置redisTemplate序列化规则
     * @param redisConnectionFactory
     * @return
     */
    //重新配置第三方bean redisTemplate的序列化规则
    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
        //先初始化一个RedisTemplate对象
        RedisTemplate<String,Object> redisTemplate=new RedisTemplate<>();

        //创建一个用于序列化字符串的序列化器
        RedisSerializer<String> redisSerializer=new StringRedisSerializer();

       //修改redisTemplate的连接工厂为传进来的redisConnectionFactory
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        //修改key序列化器和hash键序列化器为redisSerializer
        redisTemplate.setKeySerializer(redisSerializer);
        redisTemplate.setHashKeySerializer(redisSerializer);

        //修改value序列化器为我们自定义的jsonRedisSerializer
        //jsonRedisSerializer是json格式的相互转换序列化器
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer());
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer());

        return redisTemplate;
    }

    /**
     * 自定义json序列化器
     * @return
     */
    private Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer(){
        //创建一个新的json序列化器
        Jackson2JsonRedisSerializer<Object> jsonRedisSerializer =new Jackson2JsonRedisSerializer<Object>(Object.class);
        //JSON序列化器的ObjectMapper是Jackson JSON库中的一个核心类，它用于处理Java对象与JSON之间的转换
        ObjectMapper objectMapper =new ObjectMapper();

        //修改objectMapper的序列化或反序列化过程中属性的可见性
        //JsonAutoDetect.Visibility.ANY：所有属性都可见
        //PropertyAccessor.ALL 允许访问类中的所有属性，而不考虑其访问修饰符。
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);

        //修改objectMapper的配置为即当遇到未知属性时不抛出异常。
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);

        //启用了默认类型信息，以便能够正确地反序列化对象。
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);

        //将自定的objectMapper注入到自定的json序列化器中
        jsonRedisSerializer.setObjectMapper(objectMapper);
        return jsonRedisSerializer;
    }



}
